package com.pactera.asmp;

import com.alibaba.fastjson.JSONObject;
import com.pactera.asmp.util.AuthUserConfigUtil;
import com.pactera.asmp.util.RSAUtil;
import com.pactera.asmp.vo.AutherUserInfo;
import com.pactera.asmp.vo.LicenseInfo;
import org.apache.commons.codec.binary.Base64;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * 授权main
 *
 */
public class AuthMain {
    private static Logger logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);
    public static void main( String[] args )
    {
        String path = "";
        if(args.length >1 ) {
            path = args[1];
        }
        AutherUserInfo autherUserInfo = AuthUserConfigUtil.getConfig(path);
        String autherUserJson = JSONObject.toJSONString(autherUserInfo);
        try {
            //生成公钥，私钥
            Map<String, Object> keyMap = RSAUtil.initKey();
            //保存到直到文件目录
            String publicKeyStr = RSAUtil.getPublicKeyStr(keyMap);
            String privateKeyStr = RSAUtil.getPrivateKeyStr(keyMap);
            saveKey(autherUserInfo,"privateKey", privateKeyStr);
            saveKey(autherUserInfo,"publicKey", publicKeyStr);

            //用私钥加密
            byte[] bussinessData = RSAUtil.encryptRSAByPri
                    (autherUserJson.getBytes(StandardCharsets.UTF_8),true, "UTF-8",  privateKeyStr);

            //密文产生签名
            String sign = RSAUtil.generateSign(bussinessData, privateKeyStr);

            //License对象Json
            LicenseInfo licenseInfo = new LicenseInfo();
            licenseInfo.setBussiness(Base64.encodeBase64String(bussinessData));
            licenseInfo.setPublicKey(publicKeyStr);
            licenseInfo.setSign(sign);
            //保存文件license
            String licJson =  JSONObject.toJSONString(licenseInfo);

            String pathLic = BASE_DIR + autherUserInfo.getCustomerId()+ "\\license";
            writeFile(pathLic, licJson);
            logger.info("generate license complete!");

            //读license
            File file = new File(pathLic);
            byte[] datas = getByteByFile(file);
            String json = new String(datas,"UTF-8");
            System.out.println(json);
            LicenseInfo license = JSONObject.parseObject(json,LicenseInfo.class);
            //解密
            byte[] decDatas = RSAUtil.decryptRSAByPub(Base64.decodeBase64(license.getBussiness()),
                    true,"UTF-8", license.getPublicKey());
            //验签
            boolean isOk = RSAUtil.verifySign(Base64.decodeBase64(license.getBussiness()),
                    license.getPublicKey(), license.getSign());

            AutherUserInfo bi = JSONObject.parseObject(new String(decDatas,"UTF-8"), AutherUserInfo.class);
            System.out.println("sign:"+isOk+",data:" + JSONObject.toJSON(bi));
        }catch (Exception e){
            logger.error("",e);
        }
    }

    private static final String BASE_DIR = "D:\\asmpkey\\";

    private static void saveKey(AutherUserInfo autherUserInfo, String fileName, String key){
        File file = new File(BASE_DIR+ autherUserInfo.getCustomerId());
        if(file.exists()) {
            String path = BASE_DIR + autherUserInfo.getCustomerId() + "\\" + fileName;
            writeFile(path, key);
        }else {
            boolean suc = file.mkdir();
            if (suc) {
                String path = BASE_DIR + autherUserInfo.getCustomerId() + "\\" + fileName;
                writeFile(path, key);
            } else {
                logger.info("mk dir fail");
            }
        }
    }

    private static void writeFile(String path, String content){
        FileOutputStream out = null;
        try {
            File file = new File(path);
            out = new FileOutputStream(file);
            OutputStreamWriter osw = new OutputStreamWriter(out);
            BufferedWriter bw = new BufferedWriter(osw);
            bw.write(content);
            bw.flush();
        }catch (Exception e){
            logger.error("",e);
        }finally {
            if(out!=null){
                try {
                    out.close();
                } catch (IOException e) {
                    logger.error("",e);
                }
            }
        }
    }

    private static byte[] getByteByFile(File file){
        FileInputStream in = null;
        try {
            // 一次读多个字节
            byte[] tempbytes = new byte[10240];
            int byteread = 0;
            in = new FileInputStream(file);
            logger.info("当前字节输入流中的字节数为:" + in.available());
            // 读入多个字节到字节数组中，byteread为一次读入的字节数
            while ((byteread = in.read(tempbytes)) != -1) {
                //System.out.write(tempbytes, 0, byteread);
            }
            return tempbytes;
        } catch (Exception e1) {
            logger.error("", e1);
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e1) {
                }
            }
        }
        return null;
    }
}
